package com.faithbj.service.statistics;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Service;

import com.faithbj.common.configuration.Pager;
import com.faithbj.common.model.Region;
import com.faithbj.common.utils.DateUtils;
import com.faithbj.common.utils.StateEndTimeUtil;
import com.faithbj.model.conditions.BaseInfoSearchResult;
import com.faithbj.model.conditions.InfoSearchCondition;
import com.faithbj.process.State;
import com.faithbj.process.stats.JbpmStatsService;
import com.faithbj.common.service.RegionService;
import com.faithbj.support.fp.Tuple6;
import com.faithbj.utils.SystemConfigUtil;

/**
 * 核对业务查询：基本信息查询页面service
 * @author lihao
 *
 */
@Service
public class SearchService {
	
	@Resource
	private SessionFactory sessionFactory;
	
	@Resource
	private RegionService regionService;
	
	@Resource
	private JbpmStatsService jbpmStatsService;

	@Resource
	private SystemConfigUtil systemConfigUtil;
	
	private static String DateFormatDefault = "yyyy-MM-dd HH:mm:ss";
	
	/**
	 * 查询结果：所属区县，所属街道，受理编号，委托编号，申请人代表姓名，证件类型，证件号码，信息录入日期、信息核实日期、信息导出日期，当前状态，首核责任人，报告编号，预警天数
	 * @param condition
	 * @return
	 */
	public Map queryBaseInfo(InfoSearchCondition condition) {
		Session session = sessionFactory.getCurrentSession();
		
		//通过所属区县或者街道最终得到街道id列表regionId
		List<String> regionId = new ArrayList<String>();
		if(StringUtils.isNotBlank(condition.getRegionIdOfStreet())) {
			regionId.add(condition.getRegionIdOfStreet());
		}else if(StringUtils.isNotBlank(condition.getRegionIdOfCounty())) {
			//得到这些区县ID下的所有的街道ID
			regionId.addAll(regionService.getChildRegionIdByRegionId(condition.getRegionIdOfCounty()));
		}
		
		//jbpm接口
		List<String> appList = new ArrayList<String>();
		if(StringUtils.isNotBlank(condition.getCheckState())) {
			//根据审核状态和受理时间段得到申请id列表
			int stat = Integer.parseInt(condition.getCheckState());
			appList = jbpmStatsService.getApplyIdsByStateDuring(stat, condition.getStartTime(), condition.getEndTime());
			if(appList == null || appList.isEmpty()) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("resultList", new ArrayList<BaseInfoSearchResult>());
				return map;
			}
		}
		
		//预警天数一列去掉，改为达到预警天数的那一行显示为红色。
		String select = "select c.id,c.regionId,e.entrustNumber,f.name,f.idNumber,c.createDate,c.handleTime";
		String hql = " from CheckTotal c,EntrustInfo e,FamilyMember f where c.id=e.checkTotal.id and c.id=f.checkTotal.id and f.mainApplicant=1";
		
		if(StringUtils.isNotBlank(condition.getAcceptNumber())) {
			hql += " and c.id='" + condition.getAcceptNumber() + "'";
		} else if(!appList.isEmpty()) {
			hql += " and c.id in (" + toString(appList, ",") + ")";
		}
		if(StringUtils.isNotBlank(condition.getAuthorizeNumber()))
			hql += " and e.entrustNumber='" + condition.getAuthorizeNumber() + "'";
		if(StringUtils.isNotBlank(condition.getApplicantName()))
			hql += " and f.name='" + condition.getApplicantName() + "'";
		if(StringUtils.isNotBlank(condition.getIdentity()))
			hql += " and f.idNumber='" + condition.getIdentity() +"'";
		if(!regionId.isEmpty())
			hql += " and c.regionId in (" + toString(regionId, ",") + ")";
		if(condition.getStartTime()!=null){
			hql += " and c.createDate >= '" + DateUtils.formateDate2String(DateFormatDefault, condition.getStartTime()) + "'";
		}
		if(condition.getEndTime()!=null) {
			hql += " and c.createDate <= '" + DateUtils.formateDate2String(DateFormatDefault, condition.getEndTime()) + "'";
		}
		hql += " order by c.createDate desc";
		//加入分页
		Pager pager = condition.getPager();
		if(pager == null) {
			pager = new Pager();
		}
		Integer totalCount = Integer.parseInt(Long.toString((Long) session.createQuery("select count(*)" + hql).uniqueResult()));
		pager.setTotalCount(totalCount);
		if(totalCount%pager.getPageSize() == 0) {
			pager.setPageCount(totalCount/pager.getPageSize());
		} else {
			pager.setPageCount(totalCount/pager.getPageSize() + 1);
		}
		
		Query query = session.createQuery(select + hql);
		query.setFirstResult((pager.getPageNumber() - 1) * pager.getPageSize()).setMaxResults(pager.getPageSize());
		
		List<Object[]> list = query.list();
		
		Map<String, Object> map = new HashMap<String, Object>();
		if(null != list) {
			//从jbpm接口得到其他查询结果
			Map<String, Tuple6<State, String, Date, Date, Date, Date>> jbpmMap = 
				jbpmStatsService.getApplyDetailsByApplyIds(getFirstObjectOfList(list));
			//组合result
			List<BaseInfoSearchResult> result = buildResult(list, jbpmMap);
			map.put("resultList", result);
		} else {
			map.put("resultList", new ArrayList<BaseInfoSearchResult>());
		}
		map.put("pager", pager);
		
		return map;
	}

	private List<String> getFirstObjectOfList(List<Object[]> list) {
		List<String> id = new ArrayList<String>();
		Iterator<Object[]> it = list.iterator();
		
		while(it.hasNext()) {
			id.add((String) it.next()[0]);
		}
		
		return id;
	}

	/**
	 * @param condition
	 * @param list(0-c.id,1-c.regionId,2-e.entrustNumber,3-f.name,4-f.idNumber,5-c.createDate,6-c.handleTime)
	 * @param jbpmMap(申请ID, 元组). 
	 * 元组定义: (_1-申请状态, _2-首核责任人名字, _3-受理日期, _4-街镇审核日期, _5-导入内网日期, _6-状态的起始日期)
	 * @return BaseInfoSearchResult  
	 * 查询结果：所属区县，所属街道，受理编号，委托编号，申请人代表姓名，证件号码，
	 * 信息录入日期、信息核实日期、信息导出日期，当前状态，首核责任人，报告编号，预警天数
	 */
	private List<BaseInfoSearchResult> buildResult(List<Object[]> list, Map<String, Tuple6<State, String, Date, Date, Date, Date>> jbpmMap) {
		List<BaseInfoSearchResult> result = new ArrayList<BaseInfoSearchResult>();
		Iterator<Object[]> it = list.iterator();
		
		while(it.hasNext()) {
			Object[] str = it.next();
			BaseInfoSearchResult r = new BaseInfoSearchResult();
			Region street = regionService.getRegionById((String)str[1]);
			r.setCounty(street.getParent().getName());
			r.setStreet(street.getName());
			r.setAcceptNumber((String) str[0]);
			r.setEntrustNumber((String) str[2]);
			r.setAppName((String) str[3]);
			r.setIdNumber((String) str[4]);
			Tuple6 tuple6 = jbpmMap.get((String) str[0]);
			if(tuple6 != null){
				r.setInfoCheckTime((Date)tuple6._4());
				r.setInfoInputTime((Date)tuple6._5());
				r.setFirstCheckPerson((String)tuple6._2());
				r.setStatus(((State)tuple6._1()).getName());	
				State state = (State)tuple6._1();
				Date startDate = (Date)tuple6._6();	
				r.setWarning(this.needAlarm(state, startDate));//计算本条数据是否已经到了需要预警的时候了
			}			
			r.setInfoAcceptTime((Date) str[5]);											
			r.setReportNumber((String) str[0]);
			result.add(r);
		}
		return result;
	}

	//读取每个状态的处理日期，与开始时间做累加，然后与预警天数做比较
	private boolean needAlarm(State state, Date startDate) {
		Date now = new Date();
		int alarmDays = Integer.parseInt(systemConfigUtil.getDiffDays());
		Date endDate = StateEndTimeUtil.getEndDate(state.getId(), startDate); 
		if(endDate.after(now)) {
			return true;
		}
		return false;
	}
	
	private static String toString(List<String> list, String separator) {
		StringBuffer stringBuffer = new StringBuffer();
		for (String str : list) {
			stringBuffer.append(separator + "'" + str + "'");
		}
		stringBuffer.deleteCharAt(0);
		return stringBuffer.toString();
	}
	
	public static void main(String[] args){
		List<String> list = new ArrayList<String>();
		list.add("test1");
		list.add("test2");
		System.out.println(toString(list,","));
	}
}
